package gdata;

import bluecove.Device;
import com.google.inject.Inject;
import com.google.gdata.client.GoogleService;
import com.google.gdata.data.Feed;
import com.google.gdata.data.Entry;
import com.google.gdata.data.OutOfLineContent;
import com.google.gdata.data.TextContent;
import com.google.gdata.data.HtmlTextConstruct;
import com.google.gdata.data.Category;
import com.google.gdata.util.ServiceException;

import java.util.Map;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.ArrayList;
import java.util.Set;
import java.net.URL;
import java.net.MalformedURLException;
import java.io.IOException;

import config.SimpleProperties;
import config.ConsoleUtil;

/**
 * Class description...
 *
 * @author mvu
 */
public class NotebookImpl implements Notebook{
  private final Device _device;
  private URL _allNotebooks;
  private GoogleService _myService;
  private static int i = 0;

  @Inject
  public NotebookImpl(Device device) throws MalformedURLException {
    _device = device;
    _allNotebooks = new URL("http://www.google.com/notebook/feeds/05365436891260101842");
    _myService = new GoogleService("notebook", "example");
  }

  protected Feed getAllNoteBooks() throws IOException, ServiceException {
    return _myService.getFeed(_allNotebooks, Feed.class);    
  }

  protected Feed getSingleNoteBook(Entry entry) throws IOException, ServiceException {
    String uri = ((OutOfLineContent) entry.getContent()).getUri();
    URL singleNotebook = new URL(uri);
    return _myService.getFeed(singleNotebook, Feed.class);    
  }

  public void syncNotes() throws IOException, ServiceException {
    Feed allNotes = getAllNoteBooks();
    Map<String, String> noteBooks = new HashMap<String, String>();

    SimpleProperties myProperties = new SimpleProperties();
    long lastUpdated = myProperties.getNotebookLastUpdated();
    for (Entry entry : allNotes.getEntries()) {
      if (entry.getUpdated().getValue() > lastUpdated) {
        Feed singleNote = getSingleNoteBook(entry);
        String title = singleNote.getTitle().getPlainText();
        String content = printNote(singleNote);
        noteBooks.put(title, content);
      }
    }
    _device.receive(noteBooks);
    myProperties.setNotebookLastUpdated(System.currentTimeMillis());
    ConsoleUtil.end();
  }

  protected String printNote(Feed noteBookFeed){
    Map<String, List<Entry>> sections = new HashMap<String, List<Entry>>();
    for (Entry note : noteBookFeed.getEntries()) {
      String section = getSection(note);
      if(! sections.containsKey(section)){
        sections.put(section, new ArrayList<Entry>());
      }
      sections.get(section).add(note);

    }
    StringBuffer toc = printToc(sections.keySet());
    StringBuffer html = new StringBuffer();
    html.append("<html>");
    html.append(toc);
    for(Map.Entry<String,List<Entry>> entry : sections.entrySet()){
      html.append("<a name=\"").append(entry.getKey()).append("\"/>")
        .append("<h3>").append(entry.getKey()).append("</h3>")        
        .append(printEntries(entry.getValue()));
    }    
    html.append("</html>");
    return html.toString();
  }

  private StringBuffer printToc(Set<String> keys){
    StringBuffer toc = new StringBuffer();
    for(String key : keys){
      toc.append("<a href=\"#").append(key)
              .append("\">").append(key)
              .append("</a><br/>");
    }
    return toc;
  }

  private StringBuffer printEntries(List<Entry> entries){
    StringBuffer html = new StringBuffer();
    for(Entry note : entries){
      TextContent textContent = (TextContent) note.getContent();
      String content = ((HtmlTextConstruct) textContent.getContent()).getHtml();
      html.append("<p style=\"color:")
          .append(ConsoleUtil.getNextColor(i++))
          .append(";font-weight: bold;\">")
          .append("<a href=\"#\">TOP</a><br/>")
          .append(content).append("</p>");
    }
    return html;
  }

  private String getSection(Entry note) {
    Iterator<Category> iterator = note.getCategories().iterator();
    if(iterator.hasNext()){
      return iterator.next().getLabel();
    }else{
      return "Main";
    }
  }
}
